package kq

import (
	"context"
	"encoding/json"
	"fmt"
	"strconv"

	"mall/common/globalkey"
	"mall/common/mqueuex"
	"mall/common/utils/pointy"
	"mall/service/backend/common/websocket"
	"mall/service/backend/rmq/internal/svc"
	"mall/service/order/rpc/orderclient"

	"github.com/pkg/errors"
	// "github.com/sirupsen/logrus"
	"github.com/zeromicro/go-zero/core/logx"
)

/**
 * Listening to the payment flow status change notification message queue
 */
type DeferedUpdateCartMq struct {
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

func NewDeferedUpdateCartMq(ctx context.Context, svcCtx *svc.ServiceContext) *DeferedUpdateCartMq {
	return &DeferedUpdateCartMq{
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *DeferedUpdateCartMq) Consume(_, val string) error {
	// 解析数据
	var message mqueuex.DeferredUpdateShoppingCartMessage
	if err := json.Unmarshal([]byte(val), &message); err != nil {
		logx.Errorw("DeferedUpdateCartMq.Consume json.Unmarshal err", logx.Field("detail", err.Error()))
		return err
	}

	// logrus.Info(fmt.Sprintf("DeferedUpdateCartMq message: %+v", message))

	// 执行业务..
	if err := l.execService(message); err != nil {
		logx.Errorw("DeferedUpdateCartMq.execService err", logx.Field("detail", err.Error()),
			logx.Field("val", val), logx.Field("message", fmt.Sprintf("%+v", message)))
		return err
	}

	return nil
}

// Verify and update relevant flow data
func (l *DeferedUpdateCartMq) execService(message mqueuex.DeferredUpdateShoppingCartMessage) error {
	if message.SkuQtyMap == nil {
		return errors.New(fmt.Sprintf("DeferedUpdateCartMq.execService err. Failed to update cart due to invalid param: %+v", message))
	}

	shoppingCartSpecialMap := map[uint64]*orderclient.ShoppingCartSpecialInfo{}
	for skuId, v := range message.SkuQtyMap {
		if _, ok := shoppingCartSpecialMap[skuId]; !ok {
			shoppingCartSpecialMap[skuId] = &orderclient.ShoppingCartSpecialInfo{
				Quantity:  pointy.GetPointer(v.Quantity),
				PostId:    v.PostId,
				InviterId: v.InviterId,
			}
		}
	}
	_, err := l.svcCtx.OrderRpc.BatchUpdateShoppingCart(l.ctx, &orderclient.BatchUpdateShoppingCartReq{
		SkuQtyMap: shoppingCartSpecialMap,
		UserId:    message.UserId,
		OrderId:   message.OrderId,
	})
	if err != nil {
		return errors.New(fmt.Sprintf("DeferedUpdateCartMq.execService err. Failed to update cart, err: %v , message: %+v", err, message))
	}

	if message.UserId != nil && *message.UserId > 0 {
		websocket.SendMessage(
			l.svcCtx.Config.WebSocketChatUrl,
			strconv.FormatInt(int64(globalkey.ChatMessageTypeSysShoppingCartUpdated), 10),
			strconv.FormatUint(*message.UserId, 10),
		)
	}

	return nil
}
